import asyncio
import threading
from typing import Any, Coroutine, Dict, Optional

from core.data_models import ParticipantConfig, DEFAULT_HOST_USER_ID, DEFAULT_HOST_USER_NICKNAME # Import new constants
from services.db_service import DBService
from services.llm_service import LLMService
from services.file_service import FileService # Added FileService
from core.chatroom_state import ChatroomState
# Import AgentManager later to avoid circular dependency
# from core.agent_manager import AgentManager
# internal_api_logic will also be imported later to avoid circular dependencies
# from api_interfaces.internal_api_logic import InternalApiLogic

LOGIC_LOOP: Optional[asyncio.AbstractEventLoop] = None
LOGIC_THREAD: Optional[threading.Thread] = None
CORE_SERVICES: Dict[str, Any] = {}

# 假设 run_simulation_loop 存在于某个地方，如果需要，后续会处理
# async def run_simulation_loop():
#     print("Simulation loop running...")
#     while True:
#         await asyncio.sleep(10)
#         print("Simulation loop tick.")

def _logic_thread_main():
    """
    主逻辑线程的入口点。
    初始化 asyncio 事件循环和核心服务。
    """
    global LOGIC_LOOP, CORE_SERVICES
    LOGIC_LOOP = asyncio.new_event_loop()
    asyncio.set_event_loop(LOGIC_LOOP)

    # 实例化核心服务
    db_service = DBService()
    # Ensure tables are created immediately after DBService instantiation
    # and before any service (like ChatroomState) tries to access them.
    db_service.create_tables_if_not_exist()
    
    # Ensure a default human participant exists using constants
    existing_human_config = db_service.get_participant_config_by_id(DEFAULT_HOST_USER_ID)
    if not existing_human_config:
        default_human_config = ParticipantConfig(
            participant_id=DEFAULT_HOST_USER_ID,
            nickname=DEFAULT_HOST_USER_NICKNAME,
            role="human",
            is_mvp_host=True # Assuming the main human user is the host
        )
        db_service.add_or_update_participant_config(default_human_config)
        print(f"Default participant '{DEFAULT_HOST_USER_NICKNAME}' ({DEFAULT_HOST_USER_ID}) created.")
    
    llm_service = LLMService()
    file_service = FileService() # Instantiate FileService
    chatroom_state = ChatroomState(db_service)
    
    # Import AgentManager here to break the circular import cycle
    from core.agent_manager import AgentManager
    # Pass file_service to AgentManager constructor
    agent_manager = AgentManager(db_service, llm_service, file_service)
    
    # Import and instantiate InternalApiLogic here
    from api_interfaces.internal_api_logic import InternalApiLogic
    internal_api = InternalApiLogic(db_service, agent_manager, chatroom_state, llm_service)
    CORE_SERVICES['internal_api_logic'] = internal_api

    CORE_SERVICES['db_service'] = db_service
    CORE_SERVICES['llm_service'] = llm_service
    CORE_SERVICES['file_service'] = file_service # Store FileService
    CORE_SERVICES['chatroom_state'] = chatroom_state
    CORE_SERVICES['agent_manager'] = agent_manager
    CORE_SERVICES['internal_api_logic'] = internal_api

    # Placeholder for starting the simulation loop if it's to be retained.
    # The run_simulation_loop function would need to be defined or imported here,
    # and refactored to use get_core_service for its dependencies and
    # run_in_executor for DB calls.
    # Example:
    # async def run_simulation_loop_refactored():
    #     db_service = get_core_service('db_service')
    #     agent_manager = get_core_service('agent_manager')
    #     chatroom_state = get_core_service('chatroom_state')
    #     logger.info("Refactored simulation loop starting...")
    #     # ... refactored simulation logic ...
    #     # Example DB call:
    #     # await run_in_executor(db_service.some_method, arg1)
    #     logger.info("Refactored simulation loop finished an iteration or task.")

    # if hasattr(config, 'RUN_SIMULATION') and config.RUN_SIMULATION: # Assuming a config flag
    #    LOGIC_LOOP.create_task(run_simulation_loop_refactored())

    try:
        LOGIC_LOOP.run_forever()
    finally:
        # 清理操作
        tasks = asyncio.all_tasks(LOGIC_LOOP)
        for task in tasks:
            task.cancel()
        # 等待所有任务完成取消
        # LOGIC_LOOP.run_until_complete(asyncio.gather(*tasks, return_exceptions=True)) # 这行在run_forever之后可能无法正常工作
        
        # 更安全的关闭方式
        # 首先收集所有任务
        pending_tasks = [task for task in asyncio.all_tasks(LOGIC_LOOP) if not task.done()]
        if pending_tasks:
            # 给任务一些时间完成
            LOGIC_LOOP.run_until_complete(asyncio.wait(pending_tasks, timeout=5.0))
        
        # 再次检查并取消仍在运行的任务
        for task in asyncio.all_tasks(LOGIC_LOOP):
            if not task.done():
                task.cancel()
        
        # 运行直到所有任务被取消
        if any(not task.done() for task in asyncio.all_tasks(LOGIC_LOOP)):
             LOGIC_LOOP.run_until_complete(asyncio.gather(*[task for task in asyncio.all_tasks(LOGIC_LOOP) if not task.done()], return_exceptions=True))


        LOGIC_LOOP.close()
        LOGIC_LOOP = None #显式清除

def start_logic_executor():
    """
    启动逻辑执行器：创建并启动逻辑线程。
    """
    global LOGIC_THREAD
    if LOGIC_THREAD is not None:
        # 防止重复启动
        print("Logic executor already running.")
        return

    LOGIC_THREAD = threading.Thread(target=_logic_thread_main, name="LogicThread")
    LOGIC_THREAD.daemon = True # 设置为守护线程，以便主程序退出时它也会退出
    LOGIC_THREAD.start()
    print("Logic executor started.")

def stop_logic_executor():
    """
    停止逻辑执行器：停止事件循环并等待逻辑线程结束。
    """
    global LOGIC_LOOP, LOGIC_THREAD
    if LOGIC_LOOP and LOGIC_THREAD:
        print("Stopping logic executor...")
        if LOGIC_LOOP.is_running():
            LOGIC_LOOP.call_soon_threadsafe(LOGIC_LOOP.stop)
        
        LOGIC_THREAD.join(timeout=10) # 等待线程结束，设置超时
        if LOGIC_THREAD.is_alive():
            print("Warning: Logic thread did not terminate gracefully.")
        
        LOGIC_THREAD = None
        print("Logic executor stopped.")
    else:
        print("Logic executor not running or already stopped.")


def submit_to_logic_loop(coro: Coroutine) -> asyncio.Future:
    """
    将一个协程提交到逻辑线程的事件循环中执行。

    Args:
        coro: 要执行的协程。

    Returns:
        一个 asyncio.Future 对象，可以用来获取协程的结果。

    Raises:
        Exception: 如果逻辑循环未初始化。
    """
    if not LOGIC_LOOP:
        raise Exception("Logic loop not initialized")
    if not LOGIC_LOOP.is_running():
        # 这是一个潜在的问题，如果循环没有运行，提交任务会失败
        # 可能需要更好的处理方式，例如尝试重启或抛出更具体的异常
        raise Exception("Logic loop is not running. Cannot submit coroutine.")

    future = asyncio.run_coroutine_threadsafe(coro, LOGIC_LOOP)
    return future

def get_core_service(service_name: str) -> Any:
    """
    获取已注册的核心服务实例。

    Args:
        service_name: 服务的名称 (例如 'db_service', 'chatroom_state').

    Returns:
        服务实例，如果找不到则返回 None。
    """
    return CORE_SERVICES.get(service_name)

async def run_in_executor(func, *args):
    """
    一个辅助函数，用于在 asyncio 事件循环中以线程安全的方式运行同步函数。
    这主要用于从异步代码调用同步的阻塞I/O操作（如DBService的方法）。
    """
    if not LOGIC_LOOP:
        raise Exception("Logic loop not initialized for run_in_executor")
    return await LOGIC_LOOP.run_in_executor(None, func, *args)